﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Threading;
using System.IO;
using System.Runtime.Remoting;
using CWCS.Core.Library.PLCManager;
using System.Collections.Concurrent;
using CWCS.Entity.SRM;
using CWCS.Entity.Task;
using System.Text.RegularExpressions;

namespace CWCS.BLL
{
    public delegate void DNotifyCRC(CRCObject cob, List<CRCStatus> cs, string eNotify, object oNotify);//定义一个消息代理传值给UIL

    public class BLLSRMRun : BLLBase
    {
        public event DNotifyCRC ENotifyCRCEventHandler;//传递给UIL层各种消息的事件  
        public delegate void DNotify(string type, string msg);
        public event DNotify EDNotify;
        public delegate void AsyncDelegate();


        private readonly static object objLockSC = new object();
        private readonly static object locksc = new object();
        public void Start()
        {
            DataSet ds = dal.GetEquipmentInfo();//从wcs_equipmentinfo表里得到信息
            if (ds != null)
            {
                DataTable dt = ds.Tables[0];
                if (dt.Rows.Count > 0)
                {
                    crc.GetConveryZoneInfo();//判断输送机站台信息表是否有信息，无信息则添加信息
                    crc.GetAdjustScan();
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        if (dt.Rows[i]["equipmenttype"].ToString() == "SC" && dt.Rows[i]["factory"].ToString() == "NTI")
                        {
                            AddSRM(dt.Rows[i]["equipmentnum"].ToString(), dt.Rows[i]["RIPADDR"].ToString(), int.Parse(dt.Rows[i]["rport"].ToString()), 0, dt.Rows[i]["field1"].ToString());
                            System.Threading.Thread.Sleep(100);
                        }
                    }
                    if (list_srm_object.Count > 0)
                    {
                        TaskThread = new Thread(new ThreadStart(TimeScan));
                        TaskThread.Start();

                        TaskThread1 = new Thread(new ThreadStart(TimeScan1));
                        TaskThread1.Start();
                    }
                    if (File.Exists(".\\SCAlarm.txt"))
                    {
                        FileStream fs = new FileStream(".\\SCAlarm.txt", FileMode.Open, FileAccess.Read);
                        StreamReader sr = new StreamReader(fs);
                        string strline = sr.ReadToEnd().Replace("\r", "").Replace("\n", "");
                        string[] msg = strline.Split(new char[] { ';' });
                        string[] msg2;
                        for (int i = 0; i < msg.Length; i++)
                        {
                            msg2 = msg[i].Split(new char[] { ',' });
                            if (!AlarmHash.Contains(msg2[0]) && msg2.Length > 1)
                            {
                                AlarmHash.Add(msg2[0], msg2[1]);
                            }
                        }
                    }

                }
            }
        }

        public void CloseThread()
        {
            if (TaskThread.ThreadState != ThreadState.Aborted)
                TaskThread.Abort();
            if (TaskThread1.ThreadState != ThreadState.Aborted)
                TaskThread1.Abort();
        }

        public void ReStartThread()
        {
            if (TaskThread.ThreadState != ThreadState.Running)
            {
                TaskThread = new Thread(new ThreadStart(TimeScan));
                TaskThread.Start();
            }
            if (TaskThread1.ThreadState != ThreadState.Running)
            {
                TaskThread1 = new Thread(new ThreadStart(TimeScan1));
                TaskThread1.Start();
            }
        }
        /// <summary>
        /// 更新堆垛机任务模式
        /// </summary>
        /// <param name="scno"></param>
        /// <param name="taskmode"></param>
        /// <returns></returns>
        public bool UpdateTaskModeInfo(string scno, SCTaskType tasktype)
        {
            CRCObject si = list_srm_object.Find(
                  delegate (CRCObject cc)
                  {
                      return cc.ScNo == scno;
                  }
              );

            if (si != null)
            {
                si.taskType = tasktype;
                CRCStatus css = list_srm_info.Find(
               delegate (CRCStatus info)
               {
                   return info.scno == scno;
               }
           );
                if (css != null)
                {
                    css.TaskType = tasktype.ToString();
                }
                crc.UpdateCRCStatus(scno, "Update", "0", si.zonecode);
                return true;
            }
            return false;
        }

        public bool UpdateForkNoInfo(string scno, ForkNoType forkNoType)
        {
            CRCObject si = list_srm_object.Find(
                  delegate (CRCObject cc)
                  {
                      return cc.ScNo == scno;
                  }
              );

            if (si != null)
            {
                si.forkNoType = forkNoType;
                CRCStatus css = list_srm_info.Find(
               delegate (CRCStatus info)
               {
                   return info.scno == scno;
               }
           );
                if (css != null)
                {
                    css.ForkType = forkNoType.ToString();
                }
                crc.UpdateCRCStatus(scno, "Update", "0", si.zonecode);
                return true;
            }
            return false;
        }
        private void TimeScan()
        {

            while (true)
            {
                lock (objLockSC)
                {
                    try
                    {
                        DataTable dt = crc.GetTask();//视图中已排序
                        var scDic = dt.AsEnumerable().GroupBy(f => f.Field<string>("num")).ToDictionary(f => f.Key, f => f.ToList());
                        var cos = (from co in list_srm_object
                                   join num in scDic.Keys on co.ScNo equals num
                                   join cs in list_srm_info on co.ScNo equals cs.scno
                                   where co.Port == 2000 && cs?.FunctionReport == CR_NO_FUNC.ToString() && (co.forkNoType == ForkNoType.forkNo ? (cs?.forkStatus1 == 0 && cs?.forkStatus2 == 0) :
                                   co.forkNoType == ForkNoType.forkNo1 ? cs?.forkStatus1 == 0 : cs?.forkStatus2 == 0)
                                   select co).Distinct().ToList();
                        System.Threading.Tasks.Parallel.ForEach(cos, (co) => SelectSendTask(co, scDic[co.ScNo]));
                    }
                    catch
                    {
                    }
                    Thread.Sleep(1000);
                }
            }
        }
        private void TimeScan1()
        {
            while (true)
            {
                lock (locksc)
                {
                    crc.GetNewTask();
                    Thread.Sleep(1000);
                }
            }
        }
        private const int priority = 2000;
        private static ConcurrentDictionary<string, int> dicPriority = new ConcurrentDictionary<string, int>();
        private void SelectSendTask(CRCObject co, ICollection<DataRow> rows)
        {
            CRCStatus css = list_srm_info.Find(
                   delegate (CRCStatus info)
                   {
                       return info.scno == co.ScNo;
                   }
                 );
            if (css != null)
            {
                List<WCS_subtaskInfo> wcs_SubtaskInfo_list = new List<WCS_subtaskInfo>();
                WCS_subtaskInfo taskFork1 = new WCS_subtaskInfo();//工位1任务
                WCS_subtaskInfo taskFork2 = new WCS_subtaskInfo();//工位2任务
                int forkNo = 1;
                foreach (var row in rows)
                {
                    WCS_subtaskInfo wcs_Subtaskinfo = DealWCS_subtaskInfoInfo(row);
                    if (!string.IsNullOrEmpty(row["priority"].ToString().Trim()))
                        wcs_Subtaskinfo.priority = Convert.ToInt32(row["priority"].ToString().Trim());
                    wcs_SubtaskInfo_list.Add(wcs_Subtaskinfo);
                    if (!co.waitPriority.ContainsKey(wcs_Subtaskinfo.priority))
                    {
                        co.waitPriority.Add(wcs_Subtaskinfo.priority, false);
                    }
                }
                //先下小于2000的任务
                var sendRows = rows.Where(f => f.Field<int>("priority") <= priority).ToList();

                foreach (var row in sendRows)
                {
                    //获取当前任务信息
                    WCS_subtaskInfo wcs_Subtaskinfo = DealWCS_subtaskInfoInfo(row);
                    if (co.forkNoType == ForkNoType.forkNo)
                    {
                        if (sendRows.Where(f => f.Field<int>("priority") == int.Parse(row["priority"].ToString())).ToList().Count() > 1 || co.waitPriority[int.Parse(row["priority"].ToString())])
                        {
                            wcs_SubtaskInfo_list = wcs_SubtaskInfo_list.Where(x => x.priority == int.Parse(row["priority"].ToString())).ToList();
                            SelectFork2TaskInfo(css, wcs_SubtaskInfo_list, wcs_Subtaskinfo, ref forkNo, ref taskFork1, ref taskFork2);//true 可双取。false 只能单取
                        }
                        else
                        {
                            co.waitPriority[int.Parse(row["priority"].ToString())] = true;
                            continue;
                        }
                    }
                    else
                    {
                        forkNo = co.forkNoType == ForkNoType.forkNo1 ? 1 : 2;
                        if (!SelectForkTaskInfo(co, wcs_Subtaskinfo, forkNo, ref taskFork1, ref taskFork2)) //单货叉取
                        {
                            continue;
                        }
                    }

                    if (SendTaskInfoToSC(co, row["num"].ToString(), forkNo, taskFork1, taskFork2))
                    {
                        if (co.forkNoType == ForkNoType.forkNo)
                        {
                            co.waitPriority[int.Parse(row["priority"].ToString())] = false;
                        }
                        dicPriority.AddOrUpdate(co.ScNo, row.Field<int>("priority"), (k, v) => row.Field<int>("priority"));
                        return;
                    }
                    else
                        continue;
                }
                //检查优先级
                var curPriority = dicPriority.GetOrAdd(co.ScNo, priority);
                //先下大于上一次优先级的任务
                sendRows = rows.Where(f => f.Field<int>("priority") > curPriority).ToList();
                foreach (var row in sendRows)
                {
                    //获取当前任务信息
                    WCS_subtaskInfo wcs_Subtaskinfo = DealWCS_subtaskInfoInfo(row);
                    if (co.forkNoType == ForkNoType.forkNo)
                    {
                        if (sendRows.Where(f => f.Field<int>("priority") == int.Parse(row["priority"].ToString())).ToList().Count() > 1 || co.waitPriority[int.Parse(row["priority"].ToString())])
                        {
                            wcs_SubtaskInfo_list = wcs_SubtaskInfo_list.Where(x => x.priority == int.Parse(row["priority"].ToString())).ToList();
                            SelectFork2TaskInfo(css, wcs_SubtaskInfo_list, wcs_Subtaskinfo, ref forkNo, ref taskFork1, ref taskFork2);//true 可双取。false 只能单取
                        }
                        else
                        {
                            co.waitPriority[int.Parse(row["priority"].ToString())] = true;
                            continue;
                        }
                    }
                    else
                    {
                        forkNo = co.forkNoType == ForkNoType.forkNo1 ? 1 : 2;
                        if (!SelectForkTaskInfo(co, wcs_Subtaskinfo, forkNo, ref taskFork1, ref taskFork2)) //单货叉取
                        {
                            continue;
                        }
                    }

                    if (SendTaskInfoToSC(co, row["num"].ToString(), forkNo, taskFork1, taskFork2))
                    {
                        if (co.forkNoType == ForkNoType.forkNo)
                        {
                            co.waitPriority[int.Parse(row["priority"].ToString())] = false;
                        }
                        dicPriority.AddOrUpdate(co.ScNo, row.Field<int>("priority"), (k, v) => row.Field<int>("priority"));
                        return;
                    }
                    else
                        continue;
                }
                //循环大于2000小于等于上一次优先级的任务
                sendRows = rows.Where(f => f.Field<int>("priority") > priority && f.Field<int>("priority") <= curPriority).ToList();
                foreach (var row in sendRows)
                {
                    //获取当前任务信息
                    WCS_subtaskInfo wcs_Subtaskinfo = DealWCS_subtaskInfoInfo(row);
                    if (co.forkNoType == ForkNoType.forkNo)
                    {
                        if (sendRows.Where(f => f.Field<int>("priority") == int.Parse(row["priority"].ToString())).ToList().Count() > 1 || co.waitPriority[int.Parse(row["priority"].ToString())])
                        {
                            wcs_SubtaskInfo_list = wcs_SubtaskInfo_list.Where(x => x.priority == int.Parse(row["priority"].ToString())).ToList();
                            SelectFork2TaskInfo(css, wcs_SubtaskInfo_list, wcs_Subtaskinfo, ref forkNo, ref taskFork1, ref taskFork2);//true 可双取。false 只能单取
                        }
                        else
                        {
                            co.waitPriority[int.Parse(row["priority"].ToString())] = true;
                            continue;
                        }
                    }
                    else
                    {
                        forkNo = co.forkNoType == ForkNoType.forkNo1 ? 1 : 2;
                        if (!SelectForkTaskInfo(co, wcs_Subtaskinfo, forkNo, ref taskFork1, ref taskFork2)) //单货叉取
                        {
                            continue;
                        }
                    }

                    if (SendTaskInfoToSC(co, row["num"].ToString(), forkNo, taskFork1, taskFork2))
                    {
                        if (co.forkNoType == ForkNoType.forkNo)
                        {
                            co.waitPriority[int.Parse(row["priority"].ToString())] = false;
                        }
                        dicPriority.AddOrUpdate(co.ScNo, row.Field<int>("priority"), (k, v) => row.Field<int>("priority"));
                        return;
                    }
                    else
                        continue;
                }
            }
        }
        public WCS_subtaskInfo DealWCS_subtaskInfoInfo(DataRow row)
        {
            WCS_subtaskInfo wcs_Subtaskinfo = new WCS_subtaskInfo();
            wcs_Subtaskinfo.taskno = Convert.ToInt32(row["taskno"].ToString().Trim());
            wcs_Subtaskinfo.fromstation = row["fromstation"].ToString().Trim();
            wcs_Subtaskinfo.tostation = row["tostation"].ToString().Trim();
            wcs_Subtaskinfo.barcode = row["barcode"].ToString().Trim();
            wcs_Subtaskinfo.tasktype = row["tasktype"].ToString();
            wcs_Subtaskinfo.equipmentnumber = row["num"].ToString();
            return wcs_Subtaskinfo;
        }



        public bool SendTaskInfoToSC(CRCObject co, string num, int forkNo, WCS_subtaskInfo taskFork1, WCS_subtaskInfo taskFork2)
        {
            //默认下发货叉1任务
            string fromstation = taskFork1.fromstation;
            string tostation = taskFork1.tostation;
            string taskNo = taskFork1.taskno.ToString();
            string barcode = taskFork1.barcode;
            string tasktype = taskFork1.tasktype;
            //默认给货叉2赋值
            string fromstation1 = taskFork2.fromstation;
            string tostation1 = taskFork2.tostation;
            int taskNo1 = taskFork2.taskno;
            string barcode1 = taskFork2.barcode;
            if (forkNo == 1)
            {
                fromstation1 = "";
                tostation1 = "";
                taskNo1 = 0;
                barcode1 = "";
            }
            if (forkNo == 2)
            {
                fromstation = "";
                tostation = "";
                taskNo = "0";
                barcode = "";
            }
            CRCStatus SrmInfo = list_srm_info.Find(
                delegate (CRCStatus info)
                {
                    return info.scno == num;
                }
            );
            if (SrmInfo != null)
            {
                if ((forkNo == 1 && SrmInfo.forkStatus1 != 0) || (forkNo == 2 && SrmInfo.forkStatus2 != 0)
                    || (forkNo == 3 && SrmInfo.forkStatus1 != 0 && SrmInfo.forkStatus2 != 0))
                {
                    co.BllSrm.WriteLog("S", "堆垛机编号:" + num + "发送指令失败.货叉:" + forkNo + "被占用！");
                    return false;
                }
            }
            //给堆垛机下任务
            if (co.BllSrm.SendTask(num, taskNo, fromstation, tostation, tostation, tasktype, forkNo, taskNo1, fromstation1, tostation1, tostation1))
                return true;
            return false;
        }
        public static string RemoveNotNumber(string key)
        {
            return Regex.Replace(key, @"[^\d]*", "");
        }
        /// <summary>
        /// 根据任务信息，查询出双叉信息，同时根据工位更新输送机、堆垛机任务的取货地址与目标地址
        /// </summary>
        /// <param name="wcs_SubtaskInfo_list">可下发任务列表</param>
        /// <param name="fromstation">传入起始地址</param>
        /// <param name="tostation">传入目标地址</param>
        /// <param name="taskNo">传入任务号</param>
        /// <param name="barcode">传入托盘条码</param>
        /// <param name="forkNo">反馈当前执行货叉几的任务--1：货叉1--2：货叉2--3：同时取</param>
        /// <param name="taskFork1">反馈货叉1的任务信息</param>
        /// <param name="taskFork2">货叉2的信息反馈</param>
        /// <returns>true取taskFork1、taskFork2值，false根据forkNo值取相应taskFork1、taskFork2信息 </returns>
        public bool SelectFork2TaskInfo(CRCStatus css, List<WCS_subtaskInfo> wcs_SubtaskInfo_list, WCS_subtaskInfo fistStationInfo, ref int forkNo, ref WCS_subtaskInfo taskFork1, ref WCS_subtaskInfo taskFork2)
        {
            taskFork1 = fistStationInfo;//货叉1附上默认值
            taskFork2 = fistStationInfo;//货叉2附上默认值
            string fromstation = fistStationInfo.fromstation;
            string tostation = fistStationInfo.tostation;
            string taskNo = fistStationInfo.taskno.ToString();
            string barcode = fistStationInfo.barcode;
            wcs_SubtaskInfo_list = wcs_SubtaskInfo_list.Where(x => x.fromstation.Length == fromstation.Length && x.tostation.Length == tostation.Length && x.barcode != barcode).ToList();//先过滤不相等的任务，同时将本身剔除再进行业务处理。
            #region//出库任务，需要处理相邻的库位托盘。
            if (fromstation.Length > tostation.Length)//出库任务，需要处理相邻的库位托盘。
            {
                if (!BLLBase.converyZoneInfo.Exists(x => x.stationNo == tostation && !string.IsNullOrEmpty(x.WORKINGLOCATION1) && !string.IsNullOrEmpty(x.WORKINGLOCATION2))) return false;
                string workNo1tostation1 = BLLBase.converyZoneInfo.Where(x => x.stationNo == tostation).FirstOrDefault().WORKINGLOCATION1;//工位1
                string workNo1tostation2 = BLLBase.converyZoneInfo.Where(x => x.stationNo == tostation).FirstOrDefault().WORKINGLOCATION2;//工位2
                string workNo1tostation = workNo1tostation1;

                wcs_SubtaskInfo_list = wcs_SubtaskInfo_list.Where(x => (x.tostation == tostation || x.tostation == workNo1tostation) && x.fromstation.Length == fromstation.Length).ToList();//再次过滤不是同一个出库口的任务
                if (wcs_SubtaskInfo_list.Count > 0)
                {
                    string fromstationNotZone = RemoveNotNumber(fromstation);
                    int row = int.Parse(fromstationNotZone.Substring(0, 3)) % 2 == 0 ? 2 : 1;
                    int Column = int.Parse(fromstationNotZone.Substring(3, 3));
                    int layer = int.Parse(fromstationNotZone.Substring(6, 3));
                    foreach (var item in wcs_SubtaskInfo_list)
                    {
                        int row1 = int.Parse(item.fromstation.Substring(1, 3)) % 2 == 0 ? 2 : 1;
                        int Column1 = int.Parse(item.fromstation.Substring(4, 3));
                        int layer1 = int.Parse(item.fromstation.Substring(7, 3));
                        bool workNo1UpdateOK = false;
                        bool workNo2UpdateOK = false;

                        //化成堆垛机不可同时取放
                        if (fistStationInfo.equipmentnumber == "SC02")
                        {
                            if (fistStationInfo.tostation == "1014" || fistStationInfo.tostation == "1016")
                            {
                                //优先给货叉2发送指令  且需要将较大列优先发送
                                if (Column - Column1 > 0)
                                {
                                    if (UpdateTaskStation(barcode, taskNo, tostation, workNo1tostation2))//更新货叉2的目标地址
                                    {
                                        forkNo = 2;
                                        taskFork2 = fistStationInfo;
                                        return false;
                                    }
                                }
                                else
                                {
                                    if (UpdateTaskStation(item.barcode, item.taskno.ToString(), item.tostation, workNo1tostation2))//更新货叉2的目标地址
                                    {
                                        forkNo = 2;
                                        taskFork2 = item;
                                        return false;
                                    }
                                }
                            }
                            else
                            {   //优先给货叉1发送指令  且需要将较小列优先发送
                                if (Column - Column1 > 0)
                                {
                                    if (UpdateTaskStation(item.barcode, item.taskno.ToString(), item.tostation, workNo1tostation1))//更新货叉1的目标地址
                                    {
                                        forkNo = 1;
                                        taskFork1 = item;
                                        return false;
                                    }
                                }
                                else
                                {
                                    if (UpdateTaskStation(barcode, taskNo, tostation, workNo1tostation1))//更新货叉1的目标地址
                                    {
                                        forkNo = 1;
                                        taskFork1 = fistStationInfo;
                                        return false;
                                    }
                                }
                            }
                        }

                        if (row1 == row && layer == layer1 && Math.Abs(Column - Column1) == 1)
                        {
                            if (fistStationInfo.equipmentnumber == "SC01")
                            {
                                if ((Column - Column1) == -1)//列数小的为工位2
                                {
                                    if (UpdateTaskStation(barcode, taskNo, tostation, workNo1tostation2))//更新货叉2的目标地址
                                    {
                                        workNo2UpdateOK = true;
                                        taskFork2.tostation = workNo1tostation2;
                                    }
                                    if (UpdateTaskStation(item.barcode, item.taskno.ToString(), item.tostation, workNo1tostation1))//更新货叉1的目标地址
                                    {
                                        workNo1UpdateOK = true;
                                        taskFork1 = item;
                                    }
                                }
                                else
                                {
                                    if (UpdateTaskStation(barcode, taskNo, tostation, workNo1tostation1))//更新货叉1的目标地址
                                    {
                                        workNo1UpdateOK = true;
                                        taskFork1.tostation = workNo1tostation1;
                                    }
                                    if (UpdateTaskStation(item.barcode, item.taskno.ToString(), item.tostation, workNo1tostation2))//更新货叉2的目标地址
                                    {
                                        workNo2UpdateOK = true;
                                        taskFork2 = item;
                                    }
                                }
                            }
                            if (fistStationInfo.equipmentnumber == "SC05")
                            {
                                if ((Column - Column1) == -1)//列数小的为工位1
                                {
                                    if (UpdateTaskStation(barcode, taskNo, tostation, workNo1tostation1))//更新货叉1的目标地址
                                    {
                                        workNo1UpdateOK = true;
                                        taskFork1.tostation = workNo1tostation1;
                                    }
                                    if (UpdateTaskStation(item.barcode, item.taskno.ToString(), item.tostation, workNo1tostation2))//更新货叉2的目标地址
                                    {
                                        workNo2UpdateOK = true;
                                        taskFork2 = item;
                                    }
                                }
                                else
                                {
                                    if (UpdateTaskStation(barcode, taskNo, tostation, workNo1tostation2))//更新货叉2的目标地址
                                    {
                                        workNo2UpdateOK = true;
                                        taskFork2.tostation = workNo1tostation2;
                                    }
                                    if (UpdateTaskStation(item.barcode, item.taskno.ToString(), item.tostation, workNo1tostation1))//更新货叉1的目标地址
                                    {
                                        workNo1UpdateOK = true;
                                        taskFork1 = item;
                                    }
                                }
                            }
                            int taskFork1Column = int.Parse(taskFork1.fromstation.Substring(4, 3));
                            int taskFork2Column = int.Parse(taskFork2.fromstation.Substring(4, 3));

                            // SC01堆垛机8/9列  18/19列不可同时取  
                            if (fistStationInfo.equipmentnumber == "SC01" && ((taskFork1Column == 9 && taskFork2Column == 8) ||
                                (taskFork1Column == 19 && taskFork2Column == 18)))
                            {
                                if (fistStationInfo.tostation == "1203" || fistStationInfo.tostation == "1200")
                                {
                                    forkNo = 2;
                                    taskFork2 = (Column - Column1) > 0 ? item : fistStationInfo;  //优先将小列发给货叉2
                                    return false;
                                }
                                else
                                {
                                    forkNo = 1;
                                    taskFork1 = (Column - Column1) > 0 ? fistStationInfo : item;//优先将大列发给货叉1
                                    return false;
                                }
                            }
                            //分容堆垛机 当货叉2是单数列时不可同时取
                            if (fistStationInfo.equipmentnumber == "SC05" && taskFork2Column % 2 != 0)
                            {
                                if (fistStationInfo.tostation == "1752" || fistStationInfo.tostation == "1750")
                                {
                                    forkNo = 2;
                                    taskFork2 = (Column - Column1) > 0 ? fistStationInfo : item;  //优先将大列发给货叉2
                                    return false;
                                }
                                else
                                {
                                    forkNo = 1;
                                    taskFork1 = (Column - Column1) > 0 ? item : fistStationInfo;//优先将小列发给货叉1
                                    return false;
                                }
                            }
                            if (workNo1UpdateOK && workNo2UpdateOK)
                            {
                                forkNo = 3;//可同时取货。
                                return true;
                            }
                        }
                        else
                        {
                            if (fistStationInfo.equipmentnumber == "SC01")
                            {
                                if (fistStationInfo.tostation == "1203" || fistStationInfo.tostation == "1200")
                                {
                                    //优先给货叉2发送指令  且需要将较小列优先发送
                                    if (Column - Column1 > 0)
                                    {
                                        if (UpdateTaskStation(item.barcode, item.taskno.ToString(), item.tostation, workNo1tostation2))//更新货叉2的目标地址
                                        {
                                            taskFork2 = item;
                                        }
                                    }
                                    else
                                    {
                                        if (UpdateTaskStation(barcode, taskNo, tostation, workNo1tostation2))//更新货叉2的目标地址
                                        {
                                            taskFork2 = fistStationInfo;
                                        }
                                    }
                                    forkNo = 2;
                                    return false;
                                }
                                else
                                {    //优先给货叉1发送指令  且需要将较大列优先发送
                                    if (Column - Column1 > 0)
                                    {
                                        if (UpdateTaskStation(barcode, taskNo, tostation, workNo1tostation1))//更新货叉1的目标地址
                                        {
                                            taskFork1 = fistStationInfo;
                                        }
                                    }
                                    else
                                    {
                                        if (UpdateTaskStation(item.barcode, item.taskno.ToString(), item.tostation, workNo1tostation1))//更新货叉1的目标地址
                                        {
                                            taskFork1 = item;
                                        }
                                    }
                                    forkNo = 1;
                                    return false;
                                }
                            }
                            if (fistStationInfo.equipmentnumber == "SC05")
                            {
                                if (fistStationInfo.tostation == "1752" || fistStationInfo.tostation == "1750")
                                {
                                    //优先给货叉2发送指令  且需要将较大列优先发送
                                    if (Column - Column1 > 0)
                                    {
                                        if (UpdateTaskStation(barcode, taskNo, tostation, workNo1tostation2))//更新货叉2的目标地址
                                        {
                                            taskFork2 = fistStationInfo;
                                        }
                                    }
                                    else
                                    {
                                        if (UpdateTaskStation(item.barcode, item.taskno.ToString(), item.tostation, workNo1tostation2))//更新货叉2的目标地址
                                        {
                                            taskFork2 = item;
                                        }
                                    }
                                    forkNo = 2;
                                    return false;
                                }
                                else
                                {
                                    //优先给货叉1发送指令  且需要将较小列优先发送
                                    if (Column - Column1 > 0)
                                    {
                                        if (UpdateTaskStation(item.barcode, item.taskno.ToString(), item.tostation, workNo1tostation1))//更新货叉1的目标地址
                                        {
                                            taskFork1 = item;
                                        }
                                    }
                                    else
                                    {
                                        if (UpdateTaskStation(barcode, taskNo, tostation, workNo1tostation1))//更新货叉1的目标地址
                                        {
                                            taskFork1 = fistStationInfo;
                                        }
                                    }
                                    forkNo = 1;
                                    return false;
                                }
                            }
                        }
                    }
                }
                else
                {
                    forkNo = 1;
                    if (workNo1tostation1 == tostation)
                        workNo1tostation = workNo1tostation2;//工位2
                    else
                    {
                        forkNo = 2;
                        taskFork2 = taskFork1;
                    }
                }
            }
            #endregion
            #region//入库任务，需要处理输送机站台工位1与工位2，位置关系
            if (fromstation.Length < tostation.Length)//入库任务，需要处理相邻的库位托盘。
            {
                forkNo = 1;//传进来的任务工位号
                if (!BLLBase.converyZoneInfo.Exists(x => x.stationNo == fromstation && !string.IsNullOrEmpty(x.WORKINGLOCATION1) && !string.IsNullOrEmpty(x.WORKINGLOCATION2))) return false;
                string workNo1tostation1 = BLLBase.converyZoneInfo.Where(x => x.stationNo == fromstation).FirstOrDefault().WORKINGLOCATION1;//工位1
                string workNo1tostation2 = BLLBase.converyZoneInfo.Where(x => x.stationNo == fromstation).FirstOrDefault().WORKINGLOCATION2;//工位2
                string workNo1tostation = workNo1tostation1;
                if (workNo1tostation1 == fromstation)
                    workNo1tostation = workNo1tostation2;//工位2
                else
                    forkNo = 2;
                string tostationNotZone = RemoveNotNumber(tostation);
                int Column = int.Parse(tostationNotZone.Substring(3, 3));
                wcs_SubtaskInfo_list = wcs_SubtaskInfo_list.Where(x => x.fromstation == workNo1tostation).ToList();//选出另一个工位的任务
                if (wcs_SubtaskInfo_list.Count > 0)
                {
                    if (fromstation == workNo1tostation1)//该任务为工位1的任务
                    {
                        taskFork2 = wcs_SubtaskInfo_list.FirstOrDefault();
                    }
                    else//该任务为工位2的任务
                    {
                        taskFork1 = wcs_SubtaskInfo_list.FirstOrDefault();

                    }
                    forkNo = 3;
                    return true;
                }
            }
            #endregion

            #region//移库任务
            if (fromstation.Length == tostation.Length)//移库任务
            {
                if (fromstation.Length > 4)//货架移库
                {
                    string fromstationNotZone = RemoveNotNumber(fromstation);
                    int row = int.Parse(fromstationNotZone.Substring(0, 3)) % 2 == 0 ? 2 : 1;
                    int Column = int.Parse(fromstationNotZone.Substring(3, 3));
                    int layer = int.Parse(fromstationNotZone.Substring(6, 3));
                    int scPostionColum = Int32.Parse(css.Position.Substring(4, 3));

                    wcs_SubtaskInfo_list = wcs_SubtaskInfo_list.Where(x => x.tostation.Length == tostation.Length && x.fromstation.Length == fromstation.Length).ToList();
                    if (wcs_SubtaskInfo_list.Count > 0)
                    {
                        foreach (var item in wcs_SubtaskInfo_list)
                        {
                            int row1 = int.Parse(item.fromstation.Substring(1, 3)) % 2 == 0 ? 2 : 1;
                            int Column1 = int.Parse(item.fromstation.Substring(4, 3));
                            int layer1 = int.Parse(item.fromstation.Substring(7, 3));

                            if (row1 == row && layer == layer1 && Math.Abs(Column - Column1) == 1)
                            {
                                if (fistStationInfo.equipmentnumber == "SC01")
                                {
                                    if ((Column - Column1) == -1)//列数小的为工位2
                                    {
                                        taskFork2 = fistStationInfo;
                                        taskFork1 = item;
                                    }
                                    else
                                    {
                                        taskFork1 = fistStationInfo;
                                        taskFork2 = item;
                                    }
                                }
                                if (fistStationInfo.equipmentnumber == "SC05")
                                {
                                    if ((Column - Column1) == -1)//列数小的为工位1
                                    {
                                        taskFork1 = fistStationInfo;
                                        taskFork2 = item;
                                    }
                                    else
                                    {
                                        taskFork2 = fistStationInfo;
                                        taskFork1 = item;
                                    }
                                }
                                int taskFork1Column = int.Parse(taskFork1.fromstation.Substring(4, 3));
                                int taskFork2Column = int.Parse(taskFork2.fromstation.Substring(4, 3));

                                // SC01堆垛机8/9列  18/19列不可同时取  
                                if (fistStationInfo.equipmentnumber == "SC01" && ((taskFork1Column == 9 && taskFork2Column == 8) ||
                                    (taskFork1Column == 19 && taskFork2Column == 18)))
                                {
                                    if (Column >= Column1)
                                    {
                                        if (scPostionColum >= Column) forkNo = 1;
                                        else if (scPostionColum <= Column1) forkNo = 2;
                                        else forkNo = 1;
                                        return false;
                                    }
                                    else if (Column <= Column1)
                                    {
                                        if (scPostionColum <= Column) forkNo = 2;
                                        else if (scPostionColum >= Column1) forkNo = 1;
                                        else forkNo = 1;
                                        return false;
                                    }
                                }
                                //化成堆垛机不可同时取
                                if (fistStationInfo.equipmentnumber == "SC02")
                                {
                                    if (Column >= Column1)
                                    {
                                        if (scPostionColum >= Column) forkNo = 2;
                                        else if (scPostionColum <= Column1) forkNo = 1;
                                        else forkNo = 1;
                                        return false;
                                    }
                                    else if (Column <= Column1)
                                    {
                                        if (scPostionColum <= Column) forkNo = 1;
                                        else if (scPostionColum >= Column1) forkNo = 2;
                                        else forkNo = 1;
                                        return false;
                                    }
                                }
                                //分容堆垛机 当货叉2是单数列时不可同时取
                                if (fistStationInfo.equipmentnumber == "SC05" && taskFork2Column % 2 != 0)
                                {
                                    if (Column >= Column1)
                                    {
                                        if (scPostionColum >= Column) forkNo = 2;
                                        else if (scPostionColum <= Column1) forkNo = 1;
                                        else forkNo = 1;
                                        return false;
                                    }
                                    else if (Column <= Column1)
                                    {
                                        if (scPostionColum <= Column) forkNo = 1;
                                        else if (scPostionColum >= Column1) forkNo = 2;
                                        else forkNo = 1;
                                        return false;
                                    }
                                }
                                forkNo = 3;//可同时取货。
                                return true;
                            }
                            else
                            {
                                if (fistStationInfo.equipmentnumber == "SC01")
                                {
                                    if (Column >= Column1)
                                    {
                                        if (scPostionColum >= Column) forkNo = 1;
                                        else if (scPostionColum <= Column1) forkNo = 2;
                                        else if (Column1 <= scPostionColum && scPostionColum <= Column)
                                        {
                                            forkNo = (Math.Abs(scPostionColum - Column)) <= (Math.Abs(scPostionColum - Column1)) ? 1 : 2;
                                        }
                                    }
                                    else if (Column <= Column1)
                                    {
                                        if (scPostionColum <= Column) forkNo = 2;
                                        else if (scPostionColum >= Column1) forkNo = 1;
                                        else if (Column <= scPostionColum && scPostionColum <= Column1)
                                        {
                                            forkNo = (Math.Abs(scPostionColum - Column)) <= (Math.Abs(scPostionColum - Column1)) ? 1 : 2;
                                        }
                                    }
                                }
                                if (fistStationInfo.equipmentnumber == "SC05" || fistStationInfo.equipmentnumber == "SC02")
                                {
                                    if (Column >= Column1)
                                    {
                                        if (scPostionColum >= Column) forkNo = 2;
                                        else if (scPostionColum <= Column1) forkNo = 1;
                                        else forkNo = 1;
                                        return false;
                                    }
                                    else if (Column <= Column1)
                                    {
                                        if (scPostionColum <= Column) forkNo = 1;
                                        else if (scPostionColum >= Column1) forkNo = 2;
                                        else forkNo = 1;
                                        return false;
                                    }
                                }
                            }
                        }
                    }
                    forkNo = 1;
                    return false;
                }
                if (fromstation.Length == 4)
                {
                    if (!BLLBase.converyZoneInfo.Exists(x => x.stationNo == fromstation && !string.IsNullOrEmpty(x.WORKINGLOCATION1) && !string.IsNullOrEmpty(x.WORKINGLOCATION2))) return false;
                    string workNo1tostation1 = BLLBase.converyZoneInfo.Where(x => x.stationNo == fromstation).FirstOrDefault().WORKINGLOCATION1;//工位1
                    string workNo1tostation2 = BLLBase.converyZoneInfo.Where(x => x.stationNo == fromstation).FirstOrDefault().WORKINGLOCATION2;//工位2
                    string workNo1tostation = workNo1tostation1;
                    if (workNo1tostation1 == fromstation)
                        workNo1tostation = workNo1tostation2;//工位2
                    else
                        forkNo = 2;
                    wcs_SubtaskInfo_list = wcs_SubtaskInfo_list.Where(x => x.fromstation == workNo1tostation).ToList();//选出另一个工位的任务
                    if (wcs_SubtaskInfo_list.Count > 0)
                    {
                        if (fromstation == workNo1tostation1)//该任务为工位1的任务
                        {
                            taskFork2 = wcs_SubtaskInfo_list.FirstOrDefault();

                        }
                        else//该任务为工位2的任务
                        {
                            taskFork1 = wcs_SubtaskInfo_list.FirstOrDefault();
                        }
                        forkNo = 3;
                        return true;
                    }
                }
            }
            #endregion
            return false;//若无双叉任务，默认将传进来的任务单叉下发。同时告知下发货叉1还是货叉2。
        }

        public bool SelectForkTaskInfo(CRCObject co, WCS_subtaskInfo fistStationInfo, int forkNo, ref WCS_subtaskInfo taskFork1, ref WCS_subtaskInfo taskFork2)
        {
            taskFork1 = fistStationInfo;//货叉1附上默认值
            taskFork2 = fistStationInfo;//货叉2附上默认值
            string fromstation = fistStationInfo.fromstation;
            string tostation = fistStationInfo.tostation;
            string taskNo = fistStationInfo.taskno.ToString();
            string barcode = fistStationInfo.barcode;
            string workNo1tostation = string.Empty;
            string workNo1tostation1 = string.Empty;
            string workNo1tostation2 = string.Empty;
            if (co.forkType != "2")
            {
                return true;
            }
            if (fromstation.Length == 4)
            {
                workNo1tostation1 = BLLBase.converyZoneInfo.Where(x => x.stationNo == fromstation).FirstOrDefault().WORKINGLOCATION1;//工位1
                workNo1tostation2 = BLLBase.converyZoneInfo.Where(x => x.stationNo == fromstation).FirstOrDefault().WORKINGLOCATION2;//工位2
                if (forkNo == 1)
                {
                    workNo1tostation = workNo1tostation1;
                }
                else
                    workNo1tostation = workNo1tostation2;
                if (fromstation == workNo1tostation)
                    return true;
            }
            if (tostation.Length == 4)
            {
                workNo1tostation1 = BLLBase.converyZoneInfo.Where(x => x.stationNo == tostation).FirstOrDefault().WORKINGLOCATION1;//工位1
                workNo1tostation2 = BLLBase.converyZoneInfo.Where(x => x.stationNo == tostation).FirstOrDefault().WORKINGLOCATION2;//工位2

                if (forkNo == 1)
                {
                    workNo1tostation = workNo1tostation1;
                }
                else
                    workNo1tostation = workNo1tostation2;

                UpdateTaskStation(barcode, taskNo, tostation, workNo1tostation);

                return true;
            }
            if (fromstation.Length > 4 && tostation.Length > 4)
            {
                if (forkNo == 2)
                {
                    if (fistStationInfo.equipmentnumber == "SC01" && int.Parse(fromstation.Substring(4, 3)) == 18)
                    {//SC01的第18列  货叉2不可去
                        return false;
                    }
                }
                return true;
            }
            return false;
        }
        public bool SendTask(string scno, string taskno, string fork2taskno, string sourceAddress, string targetAddress, SRMCommand cmdType, string fireFlag,int forkNo)
        {
            if (forkNo == 2)
                taskno = "0";
            else if (forkNo == 1)
                fork2taskno = "0";
                CRCObject co = list_srm_object.Find(
                delegate (CRCObject info)
                {
                    return (info.ScNo == scno && info.Port.ToString().Contains("200"));
                }
            );
            if (co != null)
            {
                string taskType = "";
                //取放任务-->也是取指令
                if (cmdType == SRMCommand.PutAndGet)
                {
                    if (sourceAddress.Length > targetAddress.Length)
                    {
                        taskType = "Task_OutBound";
                    }
                    else if (sourceAddress.Length < targetAddress.Length)
                    {
                        taskType = "Task_InBound";
                    }
                    else
                    {
                        taskType = "Task_Transfer";
                    }

                    if (crc.UpdateCRCTaskInfo(scno, sourceAddress, targetAddress, targetAddress, co.taskType.ToString(), forkNo, sourceAddress, targetAddress, targetAddress))
                    {
                        //取指令
                        return co.BllSrm.SendCode(scno, CR_GETC, int.Parse(taskno), sourceAddress, fireFlag, forkNo, int.Parse(fork2taskno));
                    }

                }
                // 清除指令
                else if (cmdType == SRMCommand.CR_NO_FUNC)
                {
                    //取货完成,放货完成会自动清楚堆垛机信息
                    crc.UpdateCRCTaskInfo(scno, "", "", "", co.taskType.ToString(), forkNo, "", "", "");
                    return co.BllSrm.SendCode(scno, CR_NO_FUNC, 0, "", fireFlag);
                }
                // 取指令
                else if (cmdType == SRMCommand.CR_GETC)
                {
                    if (sourceAddress.Length > targetAddress.Length)
                    {
                        taskType = "Task_OutBound";
                    }
                    else if (sourceAddress.Length < targetAddress.Length)
                    {
                        taskType = "Task_InBound";
                    }
                    else
                    {
                        taskType = "Task_Transfer";
                    }

                    if (crc.UpdateCRCTaskInfo(scno, sourceAddress, targetAddress, targetAddress, co.taskType.ToString(), forkNo, sourceAddress, targetAddress, targetAddress))
                    {
                        //取指令
                        return co.BllSrm.SendCode(scno, CR_GETC, int.Parse(taskno), sourceAddress, fireFlag, forkNo, int.Parse(fork2taskno));
                    }
                }
                // 放指令
                else if (cmdType == SRMCommand.CR_PUTC)
                {
                    if (sourceAddress.Length > targetAddress.Length)
                    {
                        taskType = "Task_OutBound";
                    }
                    else if (sourceAddress.Length < targetAddress.Length)
                    {
                        taskType = "Task_InBound";
                    }
                    else
                    {
                        taskType = "Task_Transfer";
                    }

                    if (crc.UpdateCRCTaskInfo(scno, sourceAddress, targetAddress, targetAddress, co.taskType.ToString(), forkNo, sourceAddress, targetAddress, targetAddress))
                    {
                        //直接发送指令给堆垛机
                        return co.BllSrm.SendCode(scno, CR_PUTC, int.Parse(taskno), targetAddress, fireFlag, forkNo, int.Parse(fork2taskno));
                    }
                }
                else
                {
                    return co.BllSrm.SendCode(scno, CR_POS_GET, int.Parse(taskno), targetAddress, fireFlag, forkNo, int.Parse(fork2taskno));
                }
            }
            return false;
        }

        private void AddSRM(string scno, string ipaddress, int port, int aisle,string zone)
        {
            CRCObject srm_object = new CRCObject();
            BLLSRM srm = new BLLSRM(scno, ipaddress, port, aisle);
            srm.ENotifyTypeEventHandler += new DNotifyType(BllSrm_ENotifyTypeEventHandler);
            srm.ENotify += new BLLSRM.Notify(BllSrm_ENotify);
            srm_object.connectstatus = srm.Run();
            srm_object.BllSrm = srm;
            srm_object.ScNo = scno;
            srm_object.IpAddress = ipaddress;
            srm_object.Port = port;
            srm_object.zonecode = zone;
            list_srm_object.Add(srm_object);
        }

        private void BllSrm_ENotifyTypeEventHandler(string srmno, string port, string eNotify, object oNotify)
        {
            CRCObject cco = list_srm_object.Find(
                              delegate (CRCObject c)
                              {
                                  return c.ScNo == srmno && c.Port.ToString() == port;
                              }
                          );
            if (ENotifyCRCEventHandler != null)
                ENotifyCRCEventHandler(cco, list_srm_info, eNotify, oNotify);
        }

        private void BllSrm_ENotify(string type, string msg)
        {
            if (EDNotify != null)
                EDNotify(type, msg);
        }
    }
}
